package ifgi.potwc.ipt.upload;

import ifgi.potwc.ipt.R;
import ifgi.potwc.ipt.database.IptDatabase;
import ifgi.potwc.ipt.database.IptDatabaseManager;
import ifgi.potwc.ipt.json.IptJSONManager;
import ifgi.potwc.ipt.store.Store;
import ifgi.potwc.ipt.ui.SettingsActivity;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.json.JSONException;

import android.content.Context;
import android.content.ContextWrapper;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.widget.Toast;

/**
 * This class handles all data uploads to Cosm.
 * 
 * @author saschak.
 */
public class IptUploadManager
{
    // Cosm API keys
    private static final String API_KEY = "S_fFBZ0WcgkikDf29YcwEnVtLmiSAKx1RmgvUFQ0bndFZz0g";
//    private static final String SASCHAS_API_KEY = "Ill_qtU1jw-rwbpKv67FT_9YGVqSAKxVeVJYOUZMK0UvMD0g";

    // URL root
    private static final String URL_ROOT = "http://api.cosm.com/v2/feeds/";

    // Datastreams
    private static final String COSM_ACC = "acc"; // acceleration
    private static final String COSM_BRI = "bri"; // brightness
    private static final String COSM_HUM = "hum"; // humidity
    private static final String COSM_LAT = "lat"; // latitude
    private static final String COSM_LON = "lon"; // longitude
    private static final String COSM_TMP = "tmp"; // temperature

    // Context
    private Context ctx;

    // SharedPreferences
    private SharedPreferences prefs;

    // Database manager
    private IptDatabaseManager iptDbm;

    // JSONManager
    private IptJSONManager jm;

    public IptUploadManager(Context _context)
    {
	ctx = _context;
	prefs = SettingsActivity.getPrefs((ContextWrapper) ctx);
	iptDbm = new IptDatabaseManager(ctx);
	jm = new IptJSONManager(ctx);
    }

    // ***************************************************************************
    // Upload methods

    private boolean sendRequestToCosm(String _urlRoot, String _feedID,
	    String _cosmDatastreamName, String _message, String _datastream)
    {
	boolean requestSuccessful = false;

	// Default HttpClient
	HttpClient httpClient = new DefaultHttpClient();

	// The URL at cosm for the datastream
	String url = _urlRoot + _feedID + "/datastreams/" + _cosmDatastreamName
		+ "/datapoints";

	// Create HttpPost with the URL
	HttpPost httpPost = new HttpPost(url);

	// HttpResponse
	HttpResponse httpResponse;

	try
	{
	    // Add data
	    StringEntity se = new StringEntity(_message);
	    se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE,
		    "application/json"));

	    // Add API-Key to the header
	    httpPost.addHeader("X-ApiKey", API_KEY);

	    // Set entity
	    httpPost.setEntity(se);

	    // Execute Request
	    httpResponse = httpClient.execute(httpPost);

	    // Try updating the database depending on the response
	    if (httpResponse != null)
	    {
		// Status code of the response
		int statusCode = httpResponse.getStatusLine().getStatusCode();

		// Log.d("response", "" + statusCode);

		// In case of success the status code is 2xx
		if (statusCode / 100 == 2)
		{
		    requestSuccessful = true;

		    // Update database
		    iptDbm.markTableRowsAsUploaded(_feedID, _datastream);
		}
		else
		{
		    // Do nothing
		}
	    }
	}
	catch (Exception e)
	{
	    e.printStackTrace();
	}

	return requestSuccessful;
    }

    private boolean uploadDatastreamToCosm(String _feedID, String _datastream,
	    String _cosmDatastreamName)
    {
	boolean uploadSuccessful = false;

	try
	{
	    // Create the JSON message for the request
	    String message = jm.createJsonMessage(_datastream);

	    // Log.d("jsonMessage " + _datastream, message);

	    // Send request to Cosm
	    uploadSuccessful = sendRequestToCosm(URL_ROOT, _feedID,
		    _cosmDatastreamName, message, _datastream);
	}
	catch (JSONException e)
	{
	    e.printStackTrace();
	}

	return uploadSuccessful;
    }

    /**
     * Uploads all datastreams to Cosm.
     */
    public void uploadDatabase()
    {
	// Start UploadTask
	new UploadTask().execute();
    }

    // ***************************************************************************
    // Upload Task

    private class UploadTask extends AsyncTask<Void, Void, Boolean>
    {
	@Override
	protected Boolean doInBackground(Void... params)
	{
	    boolean uploadComplete = false;

	    // Current feed ID from SharedPreferences
	    String currentFeedID = prefs.getString(Store.FEED_ID, "");

	    if (currentFeedID.equals(""))
	    {
		// For uploading data while device is not tracking
		currentFeedID = prefs.getString(Store.LAST_FEED_ID,
			currentFeedID);
	    }

	    // Upload each single datastream, e.g. latitude, longitude, ...
	    uploadComplete = uploadDatastreamToCosm(currentFeedID,
		    IptDatabase.ACC, COSM_ACC);
	    uploadComplete = uploadDatastreamToCosm(currentFeedID,
		    IptDatabase.BRI, COSM_BRI);
	    uploadComplete = uploadDatastreamToCosm(currentFeedID,
		    IptDatabase.HUM, COSM_HUM);
	    uploadComplete = uploadDatastreamToCosm(currentFeedID,
		    IptDatabase.LAT, COSM_LAT);
	    uploadComplete = uploadDatastreamToCosm(currentFeedID,
		    IptDatabase.LON, COSM_LON);
	    uploadComplete = uploadDatastreamToCosm(currentFeedID,
		    IptDatabase.TMP, COSM_TMP);

	    return uploadComplete;
	}

	@Override
	protected void onPostExecute(Boolean result)
	{
	    super.onPostExecute(result);

	    if (result)
	    {
		Toast.makeText(ctx, R.string.databaseUploaded,
			Toast.LENGTH_SHORT).show();
	    }
	    else
	    {
		Toast.makeText(ctx, R.string.uploadIncomplete,
			Toast.LENGTH_SHORT).show();
	    }
	}
    }
}